function DayElement(dom) {
    this._dom = dom;
}

DayElement.prototype = {
    getDate: function() {
        var id = this._dom.attr('id');
        return Date.parse(id.substr(DayView.DAY_INDEX_PREFIX.length));
    },

    initNote: function(updateNoteSuccessCallback, noteDeletedFromPaletteCallback, retriveNoteCallback, showCallback){
        var me = this;
        $(this._dom.find('.note')).note({
            fireEvent: 'mouseup',
            isModal: true,
            category: 'calendar',
            updateSuccessCallback: updateNoteSuccessCallback,
            noteDeletedFromPaletteCallback: noteDeletedFromPaletteCallback,
            retriveNoteCallback: retriveNoteCallback,
            showCallback: showCallback,
            position: notePanelPosition.rightTop,
            properties: {
                'date': me.getDate().toString(CalendarConstants.JSONDateFormat)
            }
        });
    }
};


var DayView = function(day, inCurrentMonth, renderMonthTitle, isMissingTravelDay) {
    this._day = day;
    this._inCurrentMonth = inCurrentMonth;
    this._renderMonthTitle = renderMonthTitle;
    this._isMissingTravelDay = isMissingTravelDay;
};

DayView.DAY_INDEX_PREFIX = 'day_index_';
DayView.getDateIndex = function(date) {
    return date.toString(CalendarConstants.DayIdFormat);
};
DayView.getDateCellId = function(date) {
    return DayView.DAY_INDEX_PREFIX + DayView.getDateIndex(date);
};
DayView.prototype = {
    render: function() {
        var dayCell = this._createDayCell();
        var activitiesContainer = this._createActivitiesContainer();
        dayCell.append(activitiesContainer);
        return dayCell;
    },
    _createDayCell: function() {
        var day = this._day;
        var dayCell = $('<td/>').addClass(this._inCurrentMonth ? "current-month-day" : 'not-current-month-day');
        if (this._isSaturday(day)) {
            dayCell.addClass('calendar-saturday');
        }
        return dayCell;
    },

    _isSaturday: function(day) {
        return day.getDate().isSaturday();
    },

    _createActivitiesContainer: function() {
        var day = this._day;
        var activitiesContainer = $('<div class="day" id="' + DayView.getDateCellId(day.getDate()) + '"/>');

        var activities = [];
        
        if (day.getActivity()) {
            activities.push(day.getActivity());
        }

        if (day.getSecondActivity()) {
            activities.push(day.getSecondActivity());
        }

        activitiesContainer.addClass("day-" + (activities.length == 2 ? 2 : 1));
        
        this._renderNote(activitiesContainer);
        this._renderDayTitle(activitiesContainer);        
        this._renderActivities(activitiesContainer, activities);

        return activitiesContainer;
    },

    _renderNote: function(activityContainer) {
        var noteIconWrapper = $('<div style="position:relative;z-index:1;"></div>');
        var noteIcon = $('<div class="note"></div>');
        if (this._day.hasNote()) {
            noteIcon.addClass("has-note");
        }
        activityContainer.append(noteIconWrapper.append(noteIcon));
    },

    _renderDayTitle: function(activityContainer) {
        var day = this._day;
        var dayTitle = day.getDate().getDate();
        var dayLabelWrapper = $('<div style="position:relative;z-index:1;"></div>');
        var dayLabel = $('<label>' + dayTitle + '</label>');
        if (this._renderMonthTitle) {
            dayLabel.text(CalendarViewBody.getMonthTitleOf(day.getDate().getMonth()) + " " + dayTitle);
        }
        activityContainer.append(dayLabelWrapper.append(dayLabel));
    }
    ,
    _isEmptyDay: function(dayEvents) {
        return dayEvents.length === 1 && dayEvents[0].activity === DayActivity.empty && dayEvents[0].location === null;
    }
    ,

    _renderActivities: function(activitiesContainer, activities) {
        var me = this;

        activities.foreach(function(activity, index) {
            me._renderActivity(activitiesContainer, activity, index == 0);
        });
    }
    ,

    _renderOmissiveEvents: function(activitiesContainer) {
        var eventContainer = $("<div class='cell activity-multiple'></div>");
        eventContainer.html("<span>...</span>");
        eventContainer.attr('title', i18n('LABEL_SEE_MULTIPLY_ACTIVITIES'));
        activitiesContainer.append(eventContainer);
    }
    ,

    _renderActivity: function(activitiesContainer, activity, isFirstCell) {
        var activityContainer = $("<div class='cell'/>");
        if (isFirstCell) {
            activityContainer.addClass('first-cell');
        }

        if (activity !== DayActivity.empty) {
            this._renderActivityColor(activityContainer, DayActivity[activity]);
            activityContainer.attr("title", DayActivityLabelMapping[activity]);
        }

        activitiesContainer.append(activityContainer);
    },
    
    _renderActivityColor: function(activityContainer, activity) {
        var activityClass = {};
        activityClass[DayActivity.work] = 'activity-work';
        activityClass[DayActivity.sick] = 'activity-sick';
        activityClass[DayActivity.other] = 'activity-non-work';
        activityClass[DayActivity.vacation] = 'activity-vacation';
        activityClass[DayActivity.national] = 'activity-national-holiday';
        activityContainer.addClass(activityClass[activity]);
    }
    ,

    _isCrossDayTimegainCaseDepartureDay: function() {
        var me = this;
        var date = me._day.getDate();

        return !!this._day.getTravelSteps().findFirst(function(travelStep) {
            return travelStep.hasCrossDayTimegain() && date.equals(travelStep.getDepartureDate())
        });
    }
};